package com.ruoyi.learn.java.design.pattern.creator;

/**
 * 演示工厂模式（Factory Method）与抽象工厂模式（Abstract Factory）的区别。
 * 场景：创建不同风格（Windows, MacOS）的 UI 组件。
 */
public class FactoryPatternsDemo {

    //region ========== 产品接口定义 (Products) ==========

    /**
     * 产品等级结构 1: 按钮 (Button)
     */
    public interface Button {
        void render();
    }

    /**
     * 产品等级结构 2: 复选框 (Checkbox)
     */
    public interface Checkbox {
        void select();
    }

    //endregion

    //region ========== 具体产品实现 (Concrete Products) ==========

    // Windows 风格产品
    public static class WindowsButton implements Button {
        @Override
        public void render() {
            System.out.println("渲染一个 Windows 风格的按钮");
        }
    }

    public static class WindowsCheckbox implements Checkbox {
        @Override
        public void select() {
            System.out.println("选中一个 Windows 风格的复选框");
        }
    }

    // MacOS 风格产品
    public static class MacOSButton implements Button {
        @Override
        public void render() {
            System.out.println("渲染一个 MacOS 风格的按钮");
        }
    }

    public static class MacOSCheckbox implements Checkbox {
        @Override
        public void select() {
            System.out.println("选中一个 MacOS 风格的复选框");
        }
    }

    //endregion

    //region ========== 工厂模式 (Factory Method Pattern) ==========

    /**
     * 抽象工厂 (工厂方法模式): 用于创建单一类型的产品 - Button。
     * 注意：这里的 "Factory" 指的是创建 Button 的工厂。
     */
    public interface ButtonFactory {
        Button createButton(); // 工厂方法
    }

    /**
     * 具体工厂 1: 创建 Windows 风格的按钮。
     */
    public static class WindowsButtonFactory implements ButtonFactory {
        @Override
        public Button createButton() {
            return new WindowsButton();
        }
    }

    /**
     * 具体工厂 2: 创建 MacOS 风格的按钮。
     */
    public static class MacOSButtonFactory implements ButtonFactory {
        @Override
        public Button createButton() {
            return new MacOSButton();
        }
    }

    //endregion

    //region ========== 抽象工厂模式 (Abstract Factory Pattern) ==========

    /**
     * 抽象工厂 (抽象工厂模式): 用于创建一系列相关的产品 - Button 和 Checkbox。
     * 这是一个真正的 "工厂的工厂"，生产一整套 UI 组件。
     */
    public interface GUIFactory {
        Button createButton();     // 创建按钮
        Checkbox createCheckbox(); // 创建复选框
    }

    /**
     * 具体工厂 1: 生产 Windows 风格的整套 UI 组件。
     */
    public static class WindowsFactory implements GUIFactory {
        @Override
        public Button createButton() {
            return new WindowsButton();
        }

        @Override
        public Checkbox createCheckbox() {
            return new WindowsCheckbox();
        }
    }

    /**
     * 具体工厂 2: 生产 MacOS 风格的整套 UI 组件。
     */
    public static class MacOSFactory implements GUIFactory {
        @Override
        public Button createButton() {
            return new MacOSButton();
        }

        @Override
        public Checkbox createCheckbox() {
            return new MacOSCheckbox();
        }
    }

    //endregion

    //region ========== 客户端代码演示 (Client Code) ==========

    /**
     * 演示工厂模式 (Factory Method) 的使用。
     * 客户端只关心创建一种类型的产品 (Button)。
     */
    public static void demonstrateFactoryMethod() {
        System.out.println("=== 演示工厂模式 (Factory Method) ===");
        // 假设我们根据配置决定使用哪个工厂
        String osType = "windows"; // 或 "macos"

        ButtonFactory factory;
        if ("windows".equals(osType)) {
            factory = new WindowsButtonFactory();
        } else {
            factory = new MacOSButtonFactory();
        }

        // 客户端通过工厂创建按钮，不关心具体类型
        Button button = factory.createButton();
        button.render(); // 输出: 渲染一个 Windows/MacOS 风格的按钮

        // 如果想创建 Checkbox，需要另一个独立的 CheckboxFactory (工厂方法模式)
        // 这体现了工厂方法模式只关注单一产品类型。
    }

    /**
     * 演示抽象工厂模式 (Abstract Factory) 的使用。
     * 客户端关心创建一整套配套的产品 (Button + Checkbox)。
     */
    public static void demonstrateAbstractFactory() {
        System.out.println("\n=== 演示抽象工厂模式 (Abstract Factory) ===");
        // 根据操作系统选择整套 UI 组件的工厂
        String osType = "macos"; // 或 "windows"

        GUIFactory factory;
        if ("windows".equals(osType)) {
            factory = new WindowsFactory();
        } else {
            factory = new MacOSFactory();
        }

        // 使用同一个工厂创建配套的组件
        Button button = factory.createButton();
        Checkbox checkbox = factory.createCheckbox();

        // 确保创建的组件属于同一风格（产品族）
        button.render();    // 输出: 渲染一个 MacOS 风格的按钮
        checkbox.select();  // 输出: 选中一个 MacOS 风格的复选框
        // 两者风格统一，完美配套！
    }

    //endregion

    //region ========== 主函数 (Main) ==========

    public static void main(String[] args) {
        // 演示工厂模式
        demonstrateFactoryMethod();

        // 演示抽象工厂模式
        demonstrateAbstractFactory();
    }

    //endregion
}